package io.plugin.service.impl;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.RandomUtil;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import io.plugin.common.exception.GameException;
import io.plugin.common.utils.Constant;
import io.plugin.common.utils.RedisUtils;
import io.plugin.entity.ProxyItem;
import io.plugin.entity.RGPlanItem;
import io.plugin.enums.ResultEnum;
import io.plugin.utils.Retrys;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Qualifier;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.http.HttpEntity;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.http.client.ClientHttpRequestFactory;
import org.springframework.http.client.SimpleClientHttpRequestFactory;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

import javax.annotation.PostConstruct;
import java.math.BigDecimal;
import java.net.InetSocketAddress;
import java.net.Proxy;
import java.util.*;
import java.util.concurrent.Callable;

//@Service
@Slf4j
public class GameService extends Thread {

    private final Integer defaultMode = 3;
    private final Integer defaultRate = 3;
    private final Integer maxPlayRateCount = 3;
    private final Integer planType = 0;
    private final BigDecimal errorFollowMoney = BigDecimal.valueOf(0);
    private final BigDecimal defaultProfit = BigDecimal.valueOf(100);
    private ClientHttpRequestFactory defaultRequestFactory;
    private Integer useProxyIdx = 0;
    private String proxyIp = "";
    private boolean firstGetPlan = true;
    private boolean lotteryExceptionFlag = false;
    private Integer useLineIdx = 0;
    private String lineDomain = "sdftu.com";

    @Value("${ssc.game.mode}")
    Integer gameModel;

    @Value("${ssc.game.profit}")
    Integer gameProfit;

    @Qualifier("normalRestTemplate")
    @Autowired
    RestTemplate normalRestTemplate;

    @Qualifier("directRestTemplate")
    @Autowired
    RestTemplate directRestTemplate;

    @Autowired
    RedisUtils redisUtils;

    public void resetParams() {
        redisUtils.delete(Constant.GMAE_CUR_FOLLOW_COUNT);
    }

    public void addExpireProxy(String ip) {
        if (StringUtils.isBlank(ip)) {
            return;
        }
        String str = redisUtils.get(Constant.GMAE_PROXY_EXPIRE);
        List<String> expireList = JSON.parseArray(str, String.class);
        expireList.add(ip);
        redisUtils.set(Constant.GMAE_PROXY_EXPIRE, JSON.toJSONString(expireList));
    }

    public boolean expireProxyExists(String ip) {
        String str = redisUtils.get(Constant.GMAE_PROXY_EXPIRE);
        List<String> expireList = JSON.parseArray(str, String.class);
        for (String eip:expireList
             ) {
            if (eip.equals(ip)) {
                return true;
            }
        }

        return false;
    }

    public void updateTargetBalance(boolean initBlc) {
        BigDecimal profit = getProfit();
        BigDecimal balance = tryGetUserBalance();
        redisUtils.set(Constant.GMAE_USER_BALANCE, balance);

        BigDecimal oldTarBalance = getTargetBalance();
        BigDecimal tarBalance = BigDecimal.ZERO;
        if (oldTarBalance == null || oldTarBalance.compareTo(BigDecimal.ZERO) == 0) {
            tarBalance = balance.add(profit);
        } else {
            tarBalance = oldTarBalance.add(profit);
        }

        redisUtils.set(Constant.GMAE_TAR_BALANCE, tarBalance, -1);
        if (initBlc) {
            redisUtils.set(Constant.GMAE_INIT_BALANCE, balance);
        }
        gameLog(String.format("当前余额：%s 目标金额：%s", balance.toString(), tarBalance.toString()));
    }

    public Boolean waitNextRewardDay() throws InterruptedException {
        String hour = "";
        String min = "";
        Boolean start = false;
        while (!start) {
            hour = DateUtil.format(new Date(), "HH");
            Integer ihour = Integer.parseInt(hour);
            min = DateUtil.format(new Date(), "mm");
            Integer imin = Integer.parseInt(min);
            start = (ihour >= 9);
            sleep(1000 * 60);
        }

        if (start) {
            gameLog(String.format("第二天游戏开始 当前时间：%s:%s", hour, min));
            updateTargetBalance(true);
        }

        return start;
    }

    public Boolean checkRewardPlay() {

        int min = DateUtil.minute(new Date());
        int hour = DateUtil.hour(new Date(), true);

        Integer followCount = getCurFollowCount();
        gameLog(String.format("checkRewardPlay hour=%s min=%s followCount=%s", hour, min + "", followCount + ""));
        Integer expireMin = 60 - 5 * followCount;
        if (getCurFollowCount() == 1 && hour == 1 && min >= expireMin) {
            gameLog("checkRewardPlay 已经到凌晨1." + expireMin + "点且CurFollowCount=1 暂停游戏");
            return false;
        }

        return true;
    }

    @PostConstruct
    public void init() {
        try {
            gameStart();
        } catch (Exception e) {
            log.error("游戏启动失败", e);
        }
    }

    public void gameLog(String logStr) {
//        log.info("gameLog >>>>>>>>>>>>>", logStr);
        String dateStr = DateUtil.format(new Date(), DatePattern.NORM_DATE_PATTERN);
        String logKey = String.format("%s%s", Constant.GMAE_LOG_KEY, dateStr);
        String cacheLog = redisUtils.get(logKey);
        cacheLog = cacheLog == null ? "" : cacheLog;
        String dateTimeStr = DateUtil.format(new Date(), DatePattern.NORM_DATETIME_PATTERN);
        String newLogStr = "";
        if (StringUtils.isBlank(cacheLog)) {
            newLogStr = String.format("%s %s", dateTimeStr, logStr);
        } else {
            newLogStr = String.format("%s\r\n%s %s", cacheLog, dateTimeStr, logStr);
        }

        redisUtils.set(logKey, newLogStr, 48 * 3600);
    }

    public BigDecimal getProfit() {
        BigDecimal profit = redisUtils.get(Constant.GMAE_PROFIT, BigDecimal.class);
        profit = profit == null ? defaultProfit : profit;
        return profit;
    }

    public Integer getMaxPlayRateCount() {
        Integer maxCount = redisUtils.get(Constant.GMAE_MAX_PLAY_RATE_COUNT, Integer.class);
        maxCount = maxCount == null ? maxPlayRateCount : maxCount;
        return maxCount;
    }

    public BigDecimal getErrorFollowMoney() {
        BigDecimal erFollowMoney = redisUtils.get(Constant.GMAE_ERROR_FOLLOW_MONEY, BigDecimal.class);
        erFollowMoney = erFollowMoney == null ? errorFollowMoney : erFollowMoney;
        return erFollowMoney;
    }

    public Integer getMode() {
        Integer mode = redisUtils.get(Constant.GMAE_MODE, Integer.class);
        mode = mode == null ? defaultMode : mode;
        return mode;
    }

    public Integer getPlanType() {
        Integer plan = redisUtils.get(Constant.GMAE_PLAN_TYPE, Integer.class);
        plan = plan == null ? planType : plan;
        return plan;
    }

    public void addTargetBalance(BigDecimal incrMoney) {
        BigDecimal targetMoney = redisUtils.get(Constant.GMAE_TAR_BALANCE, BigDecimal.class);
        targetMoney = targetMoney == null ? getUserBalance() : targetMoney;
        redisUtils.set(Constant.GMAE_TAR_BALANCE, targetMoney.add(incrMoney), -1);
    }

    public BigDecimal getTargetBalance() {
        BigDecimal targetMoney = redisUtils.get(Constant.GMAE_TAR_BALANCE, BigDecimal.class);
        targetMoney = targetMoney == null ? BigDecimal.ZERO : targetMoney;
        return targetMoney;
    }

    public String getLastPlayStage() {
        String stage = redisUtils.get(Constant.GMAE_LAST_PLAY_STAGE, String.class);
        return stage;
    }

    public void setLastPlayStage(String stage) {
        redisUtils.set(Constant.GMAE_LAST_PLAY_STAGE, stage, -1);
    }

    public String getLastPlanCode() {
        String code = redisUtils.get(Constant.GMAE_LAST_PLAN_CODE, String.class);
        return code;
    }

    public void setLastPlanCode(String code) {
        redisUtils.set(Constant.GMAE_LAST_PLAN_CODE, code);
    }

    public String getLastPlanCount() {
        String code = redisUtils.get(Constant.GMAE_LAST_PLAN_COUNT, String.class);
        return code == null ? "" : code;
    }

    public void setLastPlanCount(String count) {
        redisUtils.set(Constant.GMAE_LAST_PLAN_COUNT, count);
    }

    public String getLastPlanStage() {
        String stage = redisUtils.get(Constant.GMAE_LAST_PLAN_STAGE, String.class);
        return stage;
    }

    public void setLastPlanStage(String stage) {
        redisUtils.set(Constant.GMAE_LAST_PLAN_STAGE, stage);
    }

    public Integer getRate() {
        Integer rate = redisUtils.get(Constant.GMAE_RATE, Integer.class);
        rate = rate == null ? defaultRate : rate;
        return rate;
    }

    public String getPrePlayCode() {
        String prePlayCode = redisUtils.get(Constant.GMAE_PRE_PLAY_CODE, String.class);
        prePlayCode = prePlayCode == null ? "" : prePlayCode;
        return prePlayCode;
    }

    public Integer getCurFollowCount() {
        Integer followCount = redisUtils.get(Constant.GMAE_CUR_FOLLOW_COUNT, Integer.class);
        followCount = followCount == null ? 1 : followCount;
        return followCount;
    }

    public void setCurFollowCount(Integer followCount) {
        redisUtils.set(Constant.GMAE_CUR_FOLLOW_COUNT, followCount);
    }

    public void addCurFollowCount(Integer followCount) {
        Integer cacheCount = getCurFollowCount();
        setCurFollowCount(cacheCount + followCount);
    }

    public Boolean getGameStart() {
        Boolean start = redisUtils.get(Constant.GMAE_START, Boolean.class);
        start = start == null ? false : start;
        return start;
    }

    public void setGameStart(Boolean flag) {
        redisUtils.set(Constant.GMAE_START, flag, -1);
    }

    public BigDecimal getBaseMoney() {
        Integer mode = getMode();
        switch (mode) {
            case 1:
                return BigDecimal.valueOf(10);
            case 2:
                return BigDecimal.valueOf(1);
            case 3:
                return BigDecimal.valueOf(0.1);
            default:
                return BigDecimal.valueOf(0.1);
        }
    }

    public void setProxy() {
        if (defaultRequestFactory == null) {
            return;
        }

        String proxyStr = redisUtils.get(Constant.GMAE_PROXY);
        if (StringUtils.isBlank(proxyStr)) {
            return;
        }

        List<ProxyItem> proxyItems = JSON.parseArray(proxyStr, ProxyItem.class);
        if (useProxyIdx >= proxyItems.size()) {
            restoreProxy();
            return;
        }

        String proxyExpireStr = redisUtils.get(Constant.GMAE_PROXY_EXPIRE);
        if (StringUtils.isBlank(proxyExpireStr)) {
            restoreProxy();
            return;
        }

        List<String> proxyExpireItems = JSON.parseArray(proxyExpireStr, String.class);
        if(proxyExpireItems.size() >= proxyItems.size()) {
            return;
        }

        gameLog("投注失败尝试切换代理网络投注...");

        boolean exists = true;
        ProxyItem proxyItem = null;
        while (exists) {
            proxyItem = proxyItems.get(useProxyIdx);
            exists = expireProxyExists(proxyItem.getIp());
            if (exists) {
                useProxyIdx++;
                if (useProxyIdx >= proxyItems.size()) {
                    restoreProxy();
                    return;
                }
                continue;
            }
        }

        SimpleClientHttpRequestFactory requestFactory = new SimpleClientHttpRequestFactory();
        gameLog(String.format("代理 ip= %s port = %s", proxyItem.getIp(), proxyItem.getPort() + ""));
        proxyIp = proxyItem.getIp();
        Proxy proxy = new Proxy(Proxy.Type.HTTP, new InetSocketAddress(proxyItem.getIp(), proxyItem.getPort()));
        requestFactory.setProxy(proxy);
        requestFactory.setConnectTimeout(30000);
        requestFactory.setReadTimeout(30000);
        normalRestTemplate.setRequestFactory(requestFactory);
    }

    public void restoreProxy() {

        if (defaultRequestFactory == null) {
            return;
        }

        if (defaultRequestFactory == normalRestTemplate.getRequestFactory()) {
            return;
        }

        proxyIp = "";
        gameLog("恢复默认代理");
        normalRestTemplate.setRequestFactory(defaultRequestFactory);
    }

    public Boolean login(boolean force) {
        if (!force) {
            String sessid = redisUtils.get(Constant.SESSID_KEY);
            if (!StringUtils.isBlank(sessid)) {
                return true;
            }
        }

        String loginUrl = "https://"+lineDomain+"/api/auth/login";
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/vnd.sc-api.v1.json");
        String bodyStr = "{\"username\":\"yjjdick\",\"password\":\"4168f00660f65be7dd660c51ba814a16\",\"validcode\":\"\",\"loginpass\":\"lKGH7loSmVHxUpMtm7NhWnJAjFcJ80o0WhOSOI6SOEo8FRRJ+k83M2V6WWOScqPgZ7koM+HFxfPuxV84KscxQ8mG/QC07V+REwu+6Hg7cosllhzTbdi9P96Z9IcNu7uxQSdYUtvXADwOc5a9Ffqq7HkvxEgSigWtx/tPdg+ANtc=\",\"nonce\":\"a1614b947539bad4d3c5a52fe625b8d6\"}";
        HttpEntity<String> formEntity = new HttpEntity<String>(bodyStr, headers);

        String response = directRestTemplate.postForObject(loginUrl, formEntity, String.class);
        if (StringUtils.isBlank(response)) {
            log.error("登录失败 response为空");
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }

        JSONObject jsonObject = JSON.parseObject(response);
        Integer status = jsonObject.getInteger("status");

        if (status != 10000) {
            log.error("登录失败 reason >>>>>>>>>>>>>>>> {}", jsonObject.toJSONString());
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }

        String sessid = jsonObject.getJSONObject("data").getJSONObject("cookie").getString("sessid");
        redisUtils.set(Constant.SESSID_KEY, sessid);
        return true;
    }
    public Boolean loginT() {


        String loginUrl = "https://s3.nikecdn.com/login?appVersion=527&experienceVersion=425&uxid=com.nike.commerce.snkrs.ios&locale=zh_CN&backendEnvironment=identity&browser=Apple%20Computer%2C%20Inc.&os=undefined&mobile=true&native=true&visit=1&visitor=1c1b9da2-5a6d-4dd5-83e3-2d8d29cf279e";
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/json");
        headers.add("Content-Length", "161");
        headers.add("Host", "s3.nikecdn.com");
        headers.add("User-Agent", "Mozilla/5.0 (iPhone; CPU iPhone OS 12_1_2 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Mobile/16C101");
        headers.add("Origin", "https://s3.nikecdn.com");
        headers.add("Referer", "https://s3.nikecdn.com/unite/mobile.html?mid=17806335041218404607517367950983512203?iOSSDKVersion=3.0.0&clientId=G64vA0b95ZruUtGk1K0FkAgaO3Ch30sj&uxId=com.nike.commerce.snkrs.ios&view=none&locale=zh_CN&backendEnvironment=identity");
        headers.add("X-NewRelic-ID", "VQYGVF5SCBADUVBRBgAGVg==");
        headers.add("Cookie", "_abck=ACA196C61B5D4D710676D50AD41FD0CC~0~YAAQLdo4fa4ymKtnAQAAnXcuUAHn5nATBUgT0cEnB4EzQn+ls1vJN8l6kZ/yQhg2WZ/8NEjnhTPbh9gtXYQ4AvnGZN9gexXHu2Eom7gAkpjXo5KVhJhD25sG2jp18G9AUcVvvKAmvO7rCKLznJGOr2Gw7FNpv4ZKipl5qJMGy4uHJzFROd/qOp7P6k1495sHyiyt0BhTgcbOxxrCc/PeGLkwYLd9YSzm+0kjfdCSxwkrG6mTRqegCsuTfZ1vrcjviQ78NgAE+J5ea69huzyppyAtvB7+it+cQN9SuplqEQ46dYvap6dLNN6G~-1~-1~-1; bm_sz=44057BF959B1B9D8CB88622779057A89~QAAQLdo4fZgymKtnAQAAinIuUNEXAkggazADFHbx6mq3+CmCWyKbctNtgcYO4ultYrQMqOMjYoB6RlZHH7cm8/7WTNfcjm3mmXJeVa+6EiYVGeRypnw3J63lwJScROaKA1JB3FHSdNmqvTMCJoxNWxw3n3/M7cYU27hW7BqjYVERj9ZaLM//ABvac4PF0kcf; guidS=77cd7115-39dd-465a-953d-44df3daf4019; guidU=1cec53a1-a827-451d-c270-27412334d177; neo.experiments=%7B%22unite-native%22%3A%7B%7D%7D; neo.swimlane=72");
        String bodyStr = "{\"username\":\"+8615317170080\",\"password\":\"Yjj900302\",\"client_id\":\"G64vA0b95ZruUtGk1K0FkAgaO3Ch30sj\",\"ux_id\":\"com.nike.commerce.snkrs.ios\",\"grant_type\":\"password\"}";
        HttpEntity<String> formEntity = new HttpEntity<String>(bodyStr, headers);

        String response = directRestTemplate.postForObject(loginUrl, formEntity, String.class);
        return true;
    }

    public Boolean tryLogin(boolean force) {
        Boolean succ = Retrys.retry(Retrys.gameRetryPolicy, 15000L, new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                Boolean succ = login(force);
                if (!succ) {
                    throw new GameException(ResultEnum.GAME_LOGIN_FAILED);
                }
                return succ;
            }
        });

        return succ == null ? false : true;
    }

    public BigDecimal tryGetUserBalance() {
        BigDecimal userBalance = Retrys.retry(Retrys.gameRetryPolicy, 15000L, new Callable<BigDecimal>() {
            @Override
            public BigDecimal call() throws Exception {
                BigDecimal balance = getUserBalance();
                if (balance == null) {
                    throw new GameException(ResultEnum.GAME_GET_USER_BALANCE_FAILED);
                }
                return balance;
            }
        });

        return userBalance == null ? BigDecimal.valueOf(0) : userBalance;
    }

    public BigDecimal getUserBalance() {
        BigDecimal userBalance = BigDecimal.valueOf(0);
        String sessid = redisUtils.get(Constant.SESSID_KEY);
        if (StringUtils.isBlank(sessid)) {
            tryLogin(true);
            throw new GameException(ResultEnum.GAME_GET_USER_BALANCE_FAILED);
        }

        String url = "https://"+lineDomain+"/user/balance";
        HttpHeaders headers = new HttpHeaders();
        headers.set("Cookie", String.format("_sessionHandler=%s", sessid));
        HttpEntity<String> formEntity = new HttpEntity<String>("", headers);

        ResponseEntity<String> response = directRestTemplate.exchange(url, HttpMethod.GET, formEntity, String.class);
        String responseBody = response.getBody();
        if (StringUtils.isBlank(responseBody)) {
            throw new GameException(ResultEnum.GAME_GET_USER_BALANCE_FAILED);
        }

        if (responseBody.contains("重新登录")) {
            gameLog("获取用户余额失败，需要重新登录，尝试中...");
            tryLogin(true);
            throw new GameException(ResultEnum.GAME_GET_USER_BALANCE_FAILED);
        }

        JSONObject jsonObject = JSONObject.parseObject(responseBody);
        if (jsonObject != null) {
            userBalance = jsonObject.getJSONObject("data").getBigDecimal("balance");
        }

        return userBalance;
    }

    public String getNetStage() {
        String url = "https://cqssc.17500.cn/tools/timelimit.html";
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/x-www-form-urlencoded");
        String bodyStr = "nourl=1";
        HttpEntity<String> formEntity = new HttpEntity<String>(bodyStr, headers);
        String response = normalRestTemplate.postForObject(url, formEntity, String.class);
        if (StringUtils.isBlank(response)) {
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }

        JSONObject jsonObject = JSONObject.parseObject(response);
        if (jsonObject != null) {
            return jsonObject.getString("issue");
        }

        return "";
    }

    public String getNetPlan(Integer type) {
        type = type == null ? 0 : type;
        String url = "http://gf.20944.com/plan.aspx?type=" + type;
        String response = normalRestTemplate.getForObject(url, String.class);
        if (StringUtils.isBlank(response)) {
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }

        String[] planArr = response.split("<br />");
        String lastPlan = "";
        for (String planStr :
                planArr) {
            if (planStr.contains("?")) {
                lastPlan = planStr;
                if (firstGetPlan) {
                    String netFollowCountStr = StringUtils.substringBetween(lastPlan, "?[", "]");
                    Integer netFollowCount = 1;
                    try {
                        netFollowCount = Integer.parseInt(netFollowCountStr);
                        if (netFollowCount > maxPlayRateCount) {
                            netFollowCount = 1;
                        }
                    } catch (Exception e) {
                        netFollowCount = 1;
                    }
                    setCurFollowCount(netFollowCount);
                    gameLog(String.format("更新跟注CurFollowCount:%s", netFollowCountStr));
                    firstGetPlan = false;
                }

                break;
            }
        }
        return lastPlan;
    }

    public Map<String, String> getLastStageInfo() {
        String url = "https://cqssc.17500.cn/tools/kjbox/lotid/cqssc.html";
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/x-www-form-urlencoded");
        String bodyStr = "";
        HttpEntity<String> formEntity = new HttpEntity<String>(bodyStr, headers);
        String response = normalRestTemplate.postForObject(url, formEntity, String.class);
        if (StringUtils.isBlank(response)) {
            log.info("【getLastStageInfo 获取数据】response is null >>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }

        JSONObject jsonObject = JSONObject.parseObject(response);
        Map<String, String> map = null;
        if (jsonObject != null) {
            map = new HashMap<>();
            String issue = jsonObject.getString("issue");
            String winnum = jsonObject.getString("winnum");
            map.put("issue", issue);
            map.put("winnum", winnum);
        }

        log.info("【getLastStageInfo 获取数据】response = {} >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", response);

        return map;
    }

    public Map<String, String> getLastStageInfoEx(String prePlayStage) {
        Date now = new Date();
        String url = "https://cqssc.17500.cn/data/cqssc.txt?t=" + now.getTime() + RandomUtil.randomNumbers(3);
        String response = normalRestTemplate.getForObject(url, String.class);
        if (StringUtils.isBlank(response)) {
            log.info("【getLastStageInfoEx 获取数据】response is null >>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }

        String[] rewardFullArr = response.split("\r\n");
        String curRewardStr = "";
        for (String item : rewardFullArr
                ) {
            if (item.contains(prePlayStage)) {
                curRewardStr = item;
                break;
            }
        }

        if (StringUtils.isBlank(curRewardStr)) {
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }

        String[] rewardInfo = curRewardStr.split(" ");
        Map<String, String> map = null;
        if (rewardInfo != null || rewardInfo.length == 6) {
            map = new HashMap<>();
            String issue = rewardInfo[0];
            String winnum = String.format("%s,%s,%s,%s,%s", rewardInfo[1], rewardInfo[2], rewardInfo[3], rewardInfo[4], rewardInfo[5]);
            map.put("issue", issue);
            map.put("winnum", winnum);
        } else {
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }

//        log.info("【getLastStageInfoEx 获取数据】response = {} >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", response);

        return map;
    }

    public Map<String, String> getLastStageInfoEx2(String prePlayStage) {
        String url = "http://103.42.176.139:801/plan.aspx?type=0";
        String response = normalRestTemplate.getForObject(url, String.class);
        if (StringUtils.isBlank(response)) {
            log.info("【getLastStageInfoEx2 获取数据】response is null >>>>>>>>>>>>>>>>>>>>>>>>>>>>>");
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }

        String curNetStage = StringUtils.substringBetween(response, "重庆SSC当前第<em>", "</em>期");

        if (!curNetStage.equals(prePlayStage)) {
            return null;
        }

        String curRewardStr = StringUtils.substringBetween(response, "开奖【<em>", "</em>】");

        String[] rewardInfo = curRewardStr.split("");
        Map<String, String> map = null;
        if (rewardInfo != null || rewardInfo.length == 5) {
            map = new HashMap<>();
            String issue = curNetStage;
            String winnum = String.format("%s,%s,%s,%s,%s", rewardInfo[0], rewardInfo[1], rewardInfo[2], rewardInfo[3], rewardInfo[4]);
            map.put("issue", issue);
            map.put("winnum", winnum);
        } else {
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }

//        log.info("【getLastStageInfoEx 获取数据】response = {} >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>", response);

        return map;
    }

    public String tryGetNetStage() {
        String netStage = Retrys.retry(Retrys.gameRetryPolicy, 1000L, new Callable<String>() {
            @Override
            public String call() {
                String newStage = getNetStage();
                if (StringUtils.isBlank(newStage)) {
                    throw new GameException(ResultEnum.GAME_GET_NEWSTAGE_FAILED);
                }
//                gameLog(String.format("最新开奖期数:%s", newStage));
                return newStage;
            }
        });

        return netStage;
    }

    public Map<String, String> tryGetLastStageInfo() {
        Map<String, String> data = Retrys.retry(Retrys.gameRetryPolicy, 1000L, new Callable<Map<String, String>>() {
            @Override
            public Map<String, String> call() throws Exception {
                Map<String, String> info = getLastStageInfo();
                if (info == null) {
                    throw new GameException(ResultEnum.GAME_GET_NEWSTAGE_FAILED);
                }
                return info;
            }
        });

        return data;
    }

    public Map<String, String> tryGetLastStageInfoEx(String prePlayStage) {
        Map<String, String> data = Retrys.retry(Retrys.gameRetryPolicy, 1000L, new Callable<Map<String, String>>() {
            @Override
            public Map<String, String> call() throws Exception {
                Map<String, String> info = getLastStageInfoEx(prePlayStage);
                if (info == null) {
                    throw new GameException(ResultEnum.GAME_GET_NEWSTAGE_FAILED);
                }
                return info;
            }
        });

        return data;
    }

    public Boolean tryPlay(String code) {
        Boolean succ = Retrys.retry(Retrys.gameRetryPolicy, 1000L, new Callable<Boolean>() {
            @Override
            public Boolean call() throws Exception {
                Boolean playSucc = play(code);
                if (playSucc == null) {
                    throw new GameException(ResultEnum.GAME_PLAY_FAILED);
                }
                return playSucc;
            }
        });

        return succ == null ? false : succ;
    }

    public String tryGetPlan(Integer type) {
        String lastPlan = Retrys.retry(Retrys.gameRetryPolicy, 1000L, new Callable<String>() {
            @Override
            public String call() throws Exception {
                String plan = getNetPlan(type);
                if (StringUtils.isBlank(plan)) {
                    throw new GameException(ResultEnum.GAME_PLAY_FAILED);
                }
                return plan;
            }
        });

        return lastPlan;
    }

    public Boolean play(String code) throws InterruptedException {
        String sessid = redisUtils.get(Constant.SESSID_KEY);
        if (StringUtils.isBlank(sessid)) {
            gameLog("sessid没找到，尝试重新登录");
            if (!tryLogin(true)) {
                gameLog("重新登录失败");
                throw new GameException(ResultEnum.GAME_PLAY_FAILED);
            }
            sessid = redisUtils.get(Constant.SESSID_KEY);
            gameLog("重新登录成功");
        }

        gameLog("获取最新开奖期数");
        String netStage = tryGetNetStage();
        if (StringUtils.isBlank(netStage)) {
            gameLog("获取最新期数失败");
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }

        gameLog(String.format("当前最新开奖期数：%s", netStage));

        String playDate = StringUtils.mid(netStage, 0, 8);
        String playStage = StringUtils.mid(netStage, 8, 3);

        String code1 = StringUtils.mid(code, 0, 1);
        String code2 = StringUtils.mid(code, 1, 1);
        String code3 = StringUtils.mid(code, 2, 1);
        String code4 = StringUtils.mid(code, 3, 1);
        String code5 = StringUtils.mid(code, 4, 1);

        List<Integer> codeIntList = new ArrayList<>();
        codeIntList.add(Integer.parseInt(code1));
        codeIntList.add(Integer.parseInt(code2));
        codeIntList.add(Integer.parseInt(code3));
        codeIntList.add(Integer.parseInt(code4));
        codeIntList.add(Integer.parseInt(code5));
        codeIntList.sort(new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return o1.compareTo(o2);
            }
        });

        code = CollectionUtil.join(codeIntList, "");

        Integer curFollowCount = getCurFollowCount();
        BigDecimal baseMoney = getBaseMoney();
        Integer rate = getRate();
        Integer mode = getMode();
        Double curPlayRateCount = Math.pow(rate, curFollowCount - 1);
        curPlayRateCount = curPlayRateCount == null ? 1 : curPlayRateCount;

        BigDecimal finalMoney = BigDecimal.valueOf(baseMoney.doubleValue() * curPlayRateCount);

        gameLog(String.format("下注参数 baseMoney=%s rate=%s mode=%s curPlayRateCount=%s finalMoney=%s", baseMoney.toString(), rate + "", mode + "", curPlayRateCount + "", finalMoney.toString()));

        String url = "https://"+lineDomain+"/lottery/?controller=game&action=play";
        HttpHeaders headers = new HttpHeaders();
        headers.add("Content-Type", "application/x-www-form-urlencoded");
        headers.add("Cookie", "_sessionHandler=" + sessid);

        String randomStr = RandomUtil.randomNumbers(4);
        String bodyStr = "lotteryid=1&curmid=50&poschoose=&flag=save&play_source=&pmode=2&lt_project_modes=" + mode + "&lt_trace_assert=no&lt_issue_start=" + playDate + "-" + playStage + "&lt_total_nums=5&lt_total_money=" + finalMoney + "&lt_project%5B%5D=%7B'type'%3A'digital'%2C'methodid'%3A30%2C'codes'%3A'%7C%7C%7C%7C" + code1 + "%26" + code2 + "%26" + code3 + "%26" + code4 + "%26" + code5 + "'%2C'menuid'%3A78%2C'nums'%3A5%2C'omodel'%3A2%2C'times'%3A" + curPlayRateCount + "%2C'money'%3A" + finalMoney + "%2C'mode'%3A" + mode + "%2C'desc'%3A'%5B%E5%AE%9A%E4%BD%8D%E8%83%86_%E5%AE%9A%E4%BD%8D%E8%83%86%5D+%5B%E5%AE%9A%E4%BD%8D%E8%83%86_%E5%AE%9A%E4%BD%8D%E8%83%86%5D+-%2C-%2C-%2C-%2C" + code + "'%7D&lt_trace_times_margin=1&lt_trace_margin=50&lt_trace_times_same=1&lt_trace_diff=1&lt_trace_times_diff=2&lt_trace_count_input=10&lt_trace_money=0&randomNum=" + randomStr + "&username=yjjdick";
        HttpEntity<String> formEntity = new HttpEntity<String>(bodyStr, headers);
        String response = "";
        try {
            response = directRestTemplate.postForObject(url, formEntity, String.class);
        } catch (Exception e) {
            gameLog("游戏下注失败，exception = " + e.getMessage());
            e.printStackTrace();
            useLineIdx++;
            switchLine();
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }

        if (StringUtils.isBlank(response)) {
            gameLog("游戏下注失败，response 为空");
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }

        if (response.contains("重新登录")) {
            gameLog("游戏下注失败，需要重新登录，尝试中...");
            tryLogin(true);
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }


        if (response.contains("505c")) {
            gameLog("response:" + response);
            String hour = DateUtil.format(new Date(), "HH");
            Integer ihour = Integer.parseInt(hour);
            if (ihour >= 2 && ihour < 10) {
                gameLog("游戏已经截止，等待第二天开始");
                waitNextRewardDay();
                gameLog("已到开奖时间，准备开始游戏");
                sleep(30000);
//                resetParams();
                throw new GameException(ResultEnum.GAME_PLAY_FAILED);
            } else {
                gameLog("游戏已经截止，但是时间并没有到达指定时间内，重新开始");
                return true;
            }
        }

        if (!response.contains("success")) {
            gameLog(String.format("投注失败，原因:%s", response));
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }

        redisUtils.set(Constant.GMAE_PRE_PLAY_CODE, code, -1);
        gameLog(String.format("下注成功，当前跟注次数:%s 最大次数:%s", getCurFollowCount() + "", getMaxPlayRateCount() + ""));
        setLastPlayStage(netStage);
        return true;
    }

    public boolean switchLine() {
        String lineStr = redisUtils.get(Constant.GMAE_LINE);
        List<String> lineArr = JSON.parseArray(lineStr, String.class);
        if (lineArr == null || lineArr.size() == 0) {
            useLineIdx = 0;
            lineDomain = "sdftu.com";
            gameLog("切换线路异常，恢复到默认线路");
            return tryLogin(true);
        }

        if (useLineIdx > lineArr.size()) {
            useLineIdx = 0;
        }

        lineDomain = lineArr.get(useLineIdx);
        gameLog("切换线路到：" + lineDomain);
        return tryLogin(true);
    }

    public void gameStart() {
        defaultRequestFactory = normalRestTemplate.getRequestFactory();

        redisUtils.delete(Constant.GMAE_LAST_PLAN_COUNT);
        redisUtils.delete(Constant.GMAE_LAST_PLAN_STAGE);
        redisUtils.delete(Constant.GMAE_LAST_PLAN_CODE);
        redisUtils.delete(Constant.GMAE_START);
        redisUtils.delete(Constant.GMAE_PRE_PLAY_CODE);
        redisUtils.delete(Constant.GMAE_LAST_PLAY_STAGE);
        redisUtils.delete(Constant.GMAE_INIT_BALANCE);
        redisUtils.delete(Constant.GMAE_TAR_BALANCE);
        redisUtils.delete(Constant.GMAE_USER_BALANCE);

        useProxyIdx = 0;
        redisUtils.set(Constant.GMAE_PROXY,"[{ip:\"221.210.120.153\",port: 54402},{ip:\"61.157.206.186\",port: 40778}]",-1);
        redisUtils.set(Constant.GMAE_PROXY_EXPIRE, "[]",-1);

        redisUtils.set(Constant.GMAE_LINE,"[\"sdftu.com\",\"nlibao.com\",\"www.sdfwu.com\",\"www.likesc888.com\",\"llhang.com\"]",-1);
        if (gameModel != null) {
            redisUtils.set(Constant.GMAE_MODE, gameModel, -1);
        }
        if (planType != null) {
            redisUtils.set(Constant.GMAE_PLAN_TYPE, planType, -1);
        }
        if (gameProfit != null) {
            redisUtils.set(Constant.GMAE_PROFIT, gameProfit);
        }
        resetParams();

        gameLog("开始,正在登录");
        Boolean loginSucc = tryLogin(false);
        if (!loginSucc) {
            gameLog("登录失败");
            return;
        }

        gameLog("登录成功,同步余额中...");
        updateTargetBalance(true);
        setGameStart(true);
        this.start();

    }

    @Override
    public void run() {
        while (!isInterrupted() && getGameStart()) {
            try {
                String netStage = tryGetNetStage();
                if (StringUtils.isBlank(netStage)) {
                    continue;
                }

                String lastPlayStage = getLastPlayStage();
                lastPlayStage = lastPlayStage == null ? "" : lastPlayStage;
                if (StringUtils.isBlank(netStage)) {
                    continue;
                }

                if (!lastPlayStage.equals(netStage)) {
                    String prePlayStage = lastPlayStage;
//                    setLastPlayStage(netStage);
                    gameLog(String.format("当前最新期数：%s", netStage));

                    if (!StringUtils.isBlank(prePlayStage)) {
                        gameLog(String.format("等待%s开奖...", prePlayStage));
                        String curNetRewardStage = "";
                        Long curNetRewardStageNum = 0L;
                        Long prePlayStageNum = Long.parseLong(prePlayStage);
                        String curNetRewardNum = "";
                        String[] rewardNumArr = null;
                        do {
                            Map<String, String> rewardNetStage = tryGetLastStageInfoEx(prePlayStage);
                            if (rewardNetStage == null) {
                                sleep(2000);
                                continue;
                            }

                            curNetRewardNum = rewardNetStage.get("winnum");
                            if (StringUtils.isBlank(curNetRewardNum)) {
                                sleep(2000);
                                continue;
                            }

                            curNetRewardStage = rewardNetStage.get("issue");
                            curNetRewardStageNum = Long.parseLong(curNetRewardStage);
                            rewardNumArr = curNetRewardNum.split(",");
                            if (rewardNumArr == null || rewardNumArr.length < 5) {
                                sleep(2000);
                                continue;
                            }

                            sleep(2000);
                        } while (StringUtils.isBlank(curNetRewardNum));

                        String lastCode = rewardNumArr[4];
                        String prePlayCode = getPrePlayCode();
                        gameLog(String.format("已开奖>>>开奖期数：%s 开奖代码：%s 上次下注代码：%s", curNetRewardStage, lastCode, prePlayCode));
                        Boolean win = false;
                        if (prePlayCode.contains(lastCode)) {
                            win = true;
                        }

                        if (win) {
                            gameLog("结果：中");
                            resetParams();
                        } else {
                            gameLog("结果：错");
                            Integer maxCount = getMaxPlayRateCount();
                            if (getCurFollowCount() == maxCount) {
                                addTargetBalance(getErrorFollowMoney());
                                BigDecimal targetMoney = getTargetBalance();
                                gameLog(String.format("连错%s次，追加目标金额，当前目标金额=%s", maxCount + "", targetMoney.toString()));
                            }

                            addCurFollowCount(1);
                            Integer curPlayRateCount = getCurFollowCount();
                            if (curPlayRateCount > maxCount) {
                                resetParams();
                            }
                        }
                    }

                    gameLog("等待计划更新...");
                    Boolean planUpdate = false;
                    String webPlanStr = "";
                    Integer curFollowCount = getCurFollowCount();
                    Integer tryGetPlanMaxCount = 6;
                    Integer tryPlanMaxCount = 1;
                    while (!planUpdate) {
                        String hour = DateUtil.format(new Date(), "HH");
                        String min = DateUtil.format(new Date(), "mm");
                        Integer imin = Integer.parseInt(min);
                        Integer ihour = Integer.parseInt(hour);
                        Boolean timeOut = false;
                        if (ihour < 22 && ihour >= 10 && imin % 10 >= 8) {
                            gameLog(String.format("获取计划失败，投注时间马上截止 curFollowCount = %s hour = %s min = %s", curFollowCount + "", hour + "", min + ""));
                            timeOut = true;
                        } else if ((ihour >= 22 || ihour <= 2) && (imin % 10) % 5 >= 3) {
                            gameLog(String.format("获取计划失败，投注时间马上截止 curFollowCount = %s hour = %s min = %s", curFollowCount + "", hour + "", min + ""));
                            timeOut = true;
                        }

                        if ((tryPlanMaxCount >= tryGetPlanMaxCount || timeOut) && curFollowCount > 1) {
                            webPlanStr = String.format("【%s】", getPrePlayCode());
                            gameLog(String.format("获取计划失败次数太多或投注时间可能马上截止了 curFollowCount = %s tryPlanMaxCount = %s tryGetPlanMaxCount = %s webPlanStr = %s", curFollowCount + "", tryPlanMaxCount + "", tryGetPlanMaxCount + "", webPlanStr));
                            break;
                        }

                        if (curFollowCount == 1) {
                            webPlanStr = tryGetPlan(getPlanType());
                        } else {
                            webPlanStr = String.format("【%s】", getPrePlayCode());
                        }

                        if (StringUtils.isBlank(webPlanStr)) {
                            gameLog("计划获取失败，等到1秒后重试...");
                            sleep(1000);
                            tryPlanMaxCount++;
                            continue;
                        }

                        String planCount = StringUtils.substringBetween(webPlanStr, "[", "]");
                        String planStage = StringUtils.mid(webPlanStr, 0, 7);
                        String lastPlanCount = getLastPlanCount() + "";
                        String lastPlanStage = getLastPlanStage();
                        lastPlanStage = lastPlanStage == null ? "" : lastPlanStage;
                        planUpdate = (!lastPlanCount.equals(planCount) || !lastPlanStage.equals(planStage));

                        if (planUpdate) {
                            setLastPlanCount(planCount);
                            setLastPlanStage(planStage);
                        }

                        sleep(2000);
                        tryGetPlanMaxCount++;
                    }

                    gameLog(String.format("计划已经更新:%s", webPlanStr));
                    String webPlanCode = StringUtils.substringBetween(webPlanStr, "【", "】");
                    gameLog(String.format("计划代码：%s", webPlanCode));

                    if (!checkRewardPlay()) {
                        gameLog("当前时间已不足以游戏最大次数，等待第二天开奖...");
                        waitNextRewardDay();
                        gameLog("等待10秒后重新开始");
                        sleep(10000);
                        continue;
                    }

                    BigDecimal userBalance = tryGetUserBalance();
                    BigDecimal tarBalance = redisUtils.get(Constant.GMAE_TAR_BALANCE, BigDecimal.class);
                    if (tarBalance.compareTo(userBalance) <= 0) {
                        gameLog("目标金额已经足够，等待第二天开奖...");
                        waitNextRewardDay();
                        gameLog("等待10秒后重新开始");
                        sleep(10000);
                        continue;
                    }

                    gameLog("开始下注,当前线路=" + lineDomain);
                    Boolean playSucc = tryPlay(webPlanCode);
                    lotteryExceptionFlag = false;
                    if (!playSucc) {
                        gameLog("下注失败");
                        firstGetPlan = true;
                        resetParams();
                    }
                    gameLog("同步用户余额");
                    userBalance = tryGetUserBalance();
                    redisUtils.set(Constant.GMAE_USER_BALANCE, userBalance);
                    tarBalance = redisUtils.get(Constant.GMAE_TAR_BALANCE, BigDecimal.class);
                    BigDecimal baseMoney = getBaseMoney();
                    gameLog(String.format("用户当前余额：%s 目标余额：%s 模式金额：%s", userBalance.toString(), tarBalance.toString(), baseMoney.toString()));

                }

                sleep(5000);
            } catch (InterruptedException e) {
                setGameStart(false);
            }
        }

        gameLog("游戏结束");
    }


    public static String getRGPlan(String issue, String seedWinnum, String planFormula,String defaultPlanCode) {
        planFormula = StringUtils.replace(planFormula, "A", seedWinnum.substring(0, 1));
        planFormula = StringUtils.replace(planFormula, "B", seedWinnum.substring(1, 2));
        planFormula = StringUtils.replace(planFormula, "C", seedWinnum.substring(2, 3));
        planFormula = StringUtils.replace(planFormula, "D", seedWinnum.substring(3, 4));
        planFormula = StringUtils.replace(planFormula, "E", seedWinnum.substring(4));
        Set<String> rgPlanCodeSet = new LinkedHashSet<>();
        String jg = "";

        // 除法
        if (planFormula.indexOf("/") > -1) {
            String[] arr = planFormula.split("/");
            Long fm = Long.valueOf(arr[0]);
            Long fz = Long.valueOf(arr[1]);
            jg = (fm / fz) + "";
        }else if(planFormula.indexOf("*") > -1) {// 乘法
            String[] arr = planFormula.split("\\*");
            Long fm = Long.valueOf(arr[0]);
            Long fz = Long.valueOf(arr[1]);
            jg = (fm * fz) + "";
        }else if(planFormula.indexOf("+") > -1) {// 加法
            String[] arr = planFormula.split("\\+");
            Long fm = Long.valueOf(arr[0]);
            Long fz = Long.valueOf(arr[1]);
            jg = (fm + fz) + "";
        }else if(planFormula.indexOf("-") > -1) {// 减法
            String[] arr = planFormula.split("\\-");
            Long fm = Long.valueOf(arr[0]);
            Long fz = Long.valueOf(arr[1]);
            jg = (fm - fz) + "";
        }

        log.info("issue>>>>>>>>>>{} jg>>>>>>>>>>>{}",issue, jg);

        String[] jgArr = jg.split("");
        int usePreIdx = 0;
        for (String jgEntry:jgArr
                ) {
            if (rgPlanCodeSet.contains(jgEntry)) {
                if(StringUtils.isBlank(defaultPlanCode)) {
                    continue;
                } else {
                    String[] preArr = defaultPlanCode.split("");
                    boolean findIt = false;
                    while (usePreIdx < 10) {
                        if (!rgPlanCodeSet.contains(preArr[usePreIdx])) {
                            jgEntry = preArr[usePreIdx];
                            findIt = true;
                            break;
                        }
                        usePreIdx++;
                    }
                    if (!findIt) {
                        continue;
                    }
                }
            }
            rgPlanCodeSet.add(jgEntry);
            if(rgPlanCodeSet.size() == 5) {
                break;
            }
        }

        if (rgPlanCodeSet.size() == 4) {
            rgPlanCodeSet.add("0");
        } else if (rgPlanCodeSet.size() < 4) {
            log.error(String.format("seedIssue = %s, planFormula = %s", seedWinnum, planFormula));
            throw new GameException(ResultEnum.GAME_RGPLAN_FAILED);
        }


        List<String> codeList = new ArrayList<>();
        for (String rgplan :rgPlanCodeSet
                ) {
            codeList.add(rgplan);
        }

        Collections.sort(codeList, new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                Integer io1 = Integer.parseInt(o1);
                Integer io2 = Integer.parseInt(o2);
                return io1.compareTo(io2);
            }
        });

        String finalCode = "";
        for (String c :codeList
                ) {
            finalCode += c;
        }

        return finalCode;
    }

    public List<RGPlanItem> getAllStageInfo(Integer mode, String formula, Integer follow) {
        Date now = new Date();
        List<RGPlanItem> rgPlanItems = new ArrayList<>();
        String url = "";
        if(mode == 1) {
            url = "https://cqssc.17500.cn/data/cqssc.txt?t=" + now.getTime() + RandomUtil.randomNumbers(3);
        }else if(mode ==2){
            url = "https://cqssc.17500.cn/data/cqssc_400.txt?t=" + now.getTime() + RandomUtil.randomNumbers(3);
        }else if(mode ==3){
            url = "https://cqssc.17500.cn/data/cqssc_2000.txt?t=" + now.getTime() + RandomUtil.randomNumbers(3);
        }else if(mode ==4){
            url = "https://cqssc.17500.cn/data/cqssc_10000.txt?t=" + now.getTime() + RandomUtil.randomNumbers(3);
        }else {
            url = "https://cqssc.17500.cn/data/cqssc.txt?t=" + now.getTime() + RandomUtil.randomNumbers(3);
        }

        String response = normalRestTemplate.getForObject(url, String.class);
        if (StringUtils.isBlank(response)) {
            throw new GameException(ResultEnum.GAME_PLAY_FAILED);
        }

        String[] rewardFullArr = response.split("\r\n");
//        int sidx = 0;
//        for(int i = 0;i<rewardFullArr.length;i++) {
//            String[] rewardInfoFirst = rewardFullArr[i].split(" ");
//            String issue = rewardInfoFirst[0];
//            if(issue.equals("20181202047")) {
//                sidx = i;
//                break;
//            }
//        }

        String[] rewardInfoFirst = rewardFullArr[0].split(" ");
        String firstIssue = rewardInfoFirst[0];
        String firstWinnum = String.format("%s%s%s%s%s", rewardInfoFirst[1], rewardInfoFirst[2], rewardInfoFirst[3], rewardInfoFirst[4], rewardInfoFirst[5]);
        String seed = firstWinnum;
        String defaultPlanCode = "0123456789";
        String prePlanCode = "";

//        Object[] rewardFullObjArr = ArrayUtil.sub(rewardFullArr, sidx, rewardFullArr.length -1);

        Integer error = 0;
        for (int i = 1; i < rewardFullArr.length; i ++) {
            String curRewardStr = rewardFullArr[i];
            String[] rewardInfo = curRewardStr.split(" ");
            Map<String, String> map = null;
            RGPlanItem rgPlanItem = new RGPlanItem();
            if (rewardInfo != null || rewardInfo.length == 6) {
                String issue = rewardInfo[0];
                rgPlanItem.setIssue(issue);
                String winnum = String.format("%s%s%s%s%s", rewardInfo[1], rewardInfo[2], rewardInfo[3], rewardInfo[4], rewardInfo[5]);
                rgPlanItem.setRewardCode(winnum);
                String planCode = "";
                if (error > 0 && error < follow) {
                    planCode = prePlanCode;

                } else {
                    planCode = getRGPlan(issue, seed, formula, defaultPlanCode);
                }

                Integer status = 0;
                if(planCode.contains(winnum.substring(4))) {
                    status = 1;
                    rgPlanItem.setContent("中" + (error + 1));
                    rgPlanItem.setPlanCode(planCode);
                    rgPlanItem.setStatus(status);
                    rgPlanItems.add(rgPlanItem);
                    error = 0;
                }else {
                    rgPlanItem.setContent("错");
                    error++;
                    if(error >= follow) {
                        rgPlanItem.setPlanCode(planCode);
                        rgPlanItem.setStatus(status);
                        rgPlanItems.add(rgPlanItem);
                        error = 0;
                    }
                }

                prePlanCode = planCode;
            }

            seed = rgPlanItem.getRewardCode();
        }


        return rgPlanItems;
    }


    public static void main(String[] args) {

        String hour = DateUtil.format(new Date(), "MM");
        Integer ihour = Integer.parseInt(hour);
        System.out.println(ihour);

    }
}